package cn.fz.consumer.amqp;

import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

import java.time.LocalTime;

@Component
@Slf4j
public class SpringRabbitListener {
    @RabbitListener(queues = "simple.queue")
    public void listenSimpleQueue(String msg) {
        log.info("SpringRabbitListener ListenSimpleQueueMessage 消费者接收到的消息: {}", msg);
    }

    /*
    要模拟多个消费者绑定同一个队列，我们在consumer服务的SpringRabbitListener中添加2个新的方法：
   实现两个消费 work.queue的监听消费消息的方法；
   一个方法消费后沉睡 20毫秒；一个消息消费后沉睡200毫秒；

   注意到这两消费者，都设置了Thead.sleep，模拟任务耗时：

消费者1 sleep了20毫秒，相当于每秒钟处理50个消息
消费者2 sleep了200毫秒，相当于每秒处理5个消息
可以看到消费者1和消费者2竟然每人消费了25条消息：

消费者1很快完成了自己的25条消息
消费者2却在缓慢的处理自己的25条消息。
也就是说消息是平均分配给每个消费者，并没有考虑到消费者的处理能力。导致1个消费者空闲，另一个消费者忙的不可开交。没有充分利用每一个消费者的能力，最终消息处理的耗时远远超过了1秒。这样显然是有问题的。

在spring中有一个简单的配置，可以解决这个问题。我们修改 mq-demo\consumer\src\main\resources\application.yml 文件，添加配置：

spring:
  rabbitmq:
    listener:
      simple:
        prefetch: 1 # 每次只能获取一条消息，处理完成才能获取下一个消息
    */
    @RabbitListener(queues = "work.queue")
    public void listenWorkQueueMessage1(String message) throws Exception {
        System.out.println("消费者1接收到消息: " + message + " " + LocalTime.now());
        try {
            Thread.sleep(20);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    @RabbitListener(queues = "work.queue")
    public void listenWorkQueueMessage2(String message) throws Exception {
        System.out.println("---消费者2接收到消息: " + message + " " + LocalTime.now());
        try {
            Thread.sleep(200);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    /*
    总结
交换机的作用是什么？

接收publisher发送的消息
将消息按照规则路由到与之绑定的队列
不能缓存消息，路由失败，消息丢失
FanoutExchange的会将消息路由到每个绑定的队列
    * */
    /*
   监听 fanout.queue1 队列的消息
    */
    @RabbitListener(queues = "fanout.queue1")
    public void listenFanoutQueue1(String message) {
        System.out.println("【消费者1】接收到消息: " + message );
    }
    /*
    监听 fanout.queue2 队列的消息
     */
    @RabbitListener(queues = "fanout.queue2")
    public void listenFanoutQueue2(String message) {
        System.out.println("【消费者2】接收到消息: " + message );
    }
}
